package modes

import (
	"fmt"
	"strconv"
	"strings"
	"time"

	"github.com/Luxurioust/excelize"
)

/*
 * 描述: 题库表
 *
 * Status 状态  0 启用  1 禁用
 * s_type 0单选 1多选 2对错 3 不定项
 *
 *****************************/

type TopicLibRe struct {
	Id          int64  `json:"t_id" `                        //题库ID
	SId         int64  `json:"t_sid" xorm:"sid"`             //科目ID
	PId         int64  `json:"t_pid" xorm:"pid"`             //项目ID
	NId         int64  `json:"t_nid" xorm:"n_id"`            //试卷ID(套题ID)
	Name        string `json:"t_name" xorm:"name"`           //题干名称
	Answer      string `json:"t_answer" xorm:"answer"`       //答案解析
	Selec       string `json:"t_selec" xorm:"selec"`         //答案选项
	Price       int64  `json:"t_price" xorm:"price"`         //价格
	At          int64  `json:"t_at" xorm:"at"`               //时间
	Fraction    int    `json:"t_fraction" xorm:"fraction"`   //题分数 加
	Deduction   int    `json:"t_deduction" xorm:"deduction"` //题分数
	SType       int    `json:"s_type" xorm:"s_type"`         //题库基础类型
	STypeName   string `json:"s_type_name" xorm:"-"`         //题库基础名称
	STypeRe     int    `json:"s_type_re" xorm:"s_type_re"`   //题库别名ID
	STypeReName string `json:"s_type_re_name" xorm:"-"`      //题库别名名称
	Start       int    `json:"t_start" xorm:"start"`         //状态
	IsAnsw      int    `json:"is_answ" xorm:"is_answ"`       // APP是否可作答，0否，1是

	Qid    int64 `json:"qid"  xorm:"qid"`         // 父节点Id
	MSort  int64 `json:"m_sort" xorm:"m_sort" `   //序号
	UpdaAt int64 `json:"upda_at" xorm:"upda_at" ` //更新时间
	IsMain int64 `json:"is_main" xorm:"is_main" ` // 是否有小题（0否，1：有）
	IsFile int64 `json:"is_file" xorm:"is_file" ` // 是否有文件路径（0否，1：有）

	IsColl       int64         `json:"is_coll" xorm:"-" `     // 是否有收藏（0否，1：有）
	Text         []TopicTextRe `json:"Text" xorm:"-"`         //状态
	Log          []TopicLogRe  `json:"Log" xorm:"-"`          //记录
	examInfo     []ExamLogRe   `json:"exam_info" xorm:"-"`    //考试记录记录
	TopicLibReCh []TopicLibRe  `json:"topic_lib_ch" xorm:"-"` //子题数据
	TopState     int           `json:"top_state" xorm:"-" `   // 作答的题的状态 0:错误 1：正确，2不可作答
	// 前端需要
	IsSee int `json:"is_see" xorm:"-" ` // 是否查看过解析 0:未查看过解析 1：查看过

}

func (this *TopicLibRe) TableName() string {
	return "topiclibre"
}

func (this *TopicLibRe) Save() (int64, error) {
	this.At = time.Now().Unix()
	this.Start = 0
	this.Price = this.Price / 100
	return Db(0).Insert(this)
}

func (this *TopicLibRe) Get() (bool, error) {
	return Db(0).Get(this)
}

func (this *TopicLibRe) IdDel() (int64, error) {
	where := fmt.Sprintf("id = %d", this.Id)
	return Db(0).Where(where).Delete(this)
}

func (this *TopicLibRe) update(where string, field string) (int64, error) {
	return Db(0).Where(where).Cols(field).Update(this)
}

func (this *TopicLibRe) IdSet(field string) (int64, error) {
	where := fmt.Sprintf("id = %d", this.Id)
	return this.update(where, field)
}

func (this *TopicLibRe) PLists(val *Pager, uid int64) error {
	list := make([]TopicLibRe, 0)
	val.TName = "topiclibre"
	val.Page--
	if val.Page <= 0 {
		val.Page = 0
	}
	var field, sort string
	field = fmt.Sprintf("%s.s_type", val.TName) // 题库类型
	if 0 == val.Rules {
		sort = fmt.Sprintf("%s asc", field)
	} else {
		sort = fmt.Sprintf("%s desc", field)
	}
	where := fmt.Sprintf("start = 0")
	val.Total, _ = Db(1).Table(val.TName).
		Where(where).
		Where(val.ToWhere()).
		Count(this)

	err := Db(1).Table(val.TName).
		Where(where).
		Where(val.ToWhere()).
		OrderBy(sort).
		Limit(val.Count, val.Page*val.Count).
		Find(&list)
	if err == nil {
		for i, row := range list {
			list[i].Text, _ = GetToptext2(row.Id)
			list[i].Log, _ = GetToplog2(row.Id, uid)
		}
		val.List = list
	}
	return err
}
func (this *TopicLibRe) Count(where string) (int64, error) {
	var val TopicLibRe
	return Db(0).Where(where).Count(&val)
}

func (this *TopicLibRe) CountRecord() (int64, error) {
	return Db(0).Where("start=0").Count(this)
}

type AllNum struct {
	Num int64 `json:"-" xorm:"num"`      //科目ID
	NId int64 `json:"t_nid" xorm:"n_id"` //题库名称介绍
}

func (this *TopicLibRe) GetAllNum() ([]AllNum, error) {
	allNums := make([]AllNum, 0)
	err := Db(0).Select(" COUNT(1) num, n_id ").Table("topiclibre").Where(" id=qid and start=0").GroupBy("n_id").Find(&allNums)
	return allNums, err
}
func (this *TopicLibRe) where(fage, count, page int, where, field string) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	var err error
	if field == "" {
		field = "id"
	}
	page--
	if 0 == fage { // 从小到大排序
		err = Db(0).Where(where).
			Asc(field).
			Limit(count, page*count).
			Find(&list)
	} else { // 从大到小排序
		err = Db(0).Where(where).
			Desc(field).
			Limit(count, page*count).
			Find(&list)
	}
	return list, err
}

func (this *TopicLibRe) GetList(nidlist []int64, sType []int64) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	tbl := Db(0).Asc("s_type").Asc("s_type_re").Asc("id").Where("start=0").In("n_id", nidlist)
	if sType[0] == -1 {
		err := tbl.Clone().Find(&list)
		return list, err
	}
	err := tbl.In("s_type_re", sType).Find(&list)
	return list, err
}
func (this *TopicLibRe) GetListByNid() ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	err := Db(0).Asc("s_type").Asc("s_type_re").Asc("id").Where("n_id= ? and start=0", this.NId).Find(&list)
	return list, err

}
func (this *TopicLibRe) GetListByNidList(nidList []int64) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	err := Db(0).Asc("s_type").Asc("s_type_re").Asc("id").Where("start=0").In("n_id", nidList).Find(&list)
	return list, err
}
func (this *TopicLibRe) GetListByTidList(tidList []int64) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	err := Db(0).Asc("s_type ").Asc("s_type_re").In("id", tidList).Find(&list)
	return list, err
}
func (this *TopicLibRe) GetListByQidList(qidList []int64) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	err := Db(0).Asc("s_type ").Asc("s_type_re").Asc("id").In("qid", qidList).Find(&list)
	return list, err
}

func (this *TopicLibRe) GetListByqidList(tidList []int64) ([]TopicLibRe, error) {
	list := make([]TopicLibRe, 0)
	err := Db(0).Asc("s_type_res_type_re").Desc("at").In("qid", tidList).Find(&list)
	return list, err

}

func GetToptext2(tid int64) ([]TopicTextRe, error) {
	list := make([]TopicTextRe, 0)
	w := fmt.Sprintf("tid = %d ", tid)
	err := Db(1).
		Where(w).
		Find(&list)
	return list, err
}

func GetToplog2(tid int64, uid int64) ([]TopicLogRe, error) {
	list := make([]TopicLogRe, 0)
	w := fmt.Sprintf("tid = %d and uid = %d ", tid, uid)
	err := Db(0).
		Where(w).
		Find(&list)
	return list, err
}
func (this *TopicLibRe) ParsingFile(file_url string) error {

	// 首先读excel
	xlsx, err := excelize.OpenFile(file_url)
	if err != nil {
		return nil
	}
	rows, err := xlsx.GetRows(xlsx.GetSheetName(xlsx.GetActiveSheetIndex()))
	var val TopicTextRe
	t_id := 0
	for i, row := range rows {
		if i == 0 {
			continue
		}
		k := strings.Contains(row[0], ".")

		if k != true {
			var lib TopicLibRe
			lib.SId = this.SId
			lib.PId = this.PId
			lib.Name = row[1]
			lib.Selec = row[2]
			lib.Answer = row[3]
			lib.Price, _ = strconv.ParseInt(row[4], 10, 64)
			lib.SType, _ = strconv.Atoi(row[5])
			lib.Fraction, _ = strconv.Atoi(row[6])
			lib.Deduction, _ = strconv.Atoi(row[7])
			lib.Save()
			t_id = int(lib.Id)
		} else {
			val.TQues = row[1]
			val.Selec = row[2]
			val.TId = int64(t_id)
			val.Save()
		}
	}
	return err
}

func (this *TopicLibRe) TAnswer(id int64) (TopicLibRe, error) {
	_, err := this.Get()
	return *this, err
}

type TQType struct {
	SType   int64  `json:"s_type" xorm:"s_type"`       //类型id
	STypeRe int64  `json:"s_type_re" xorm:"s_type_re"` //类型的别名Id
	Num     int64  `json:"num" xorm:"num"`             //某章节下该类型的数量
	Name    string `json:"name" xorm:"-"`              //名称
}

func (this *TopicLibRe) GetTQType(tqId int64) ([]TQType, error) {
	tqTypeList := make([]TQType, 0)
	err := Db(0).Select("s_type,s_type_re ,COUNT(1) num ").Table("topiclibre ").
		Join("INNER", "toplibnamere  ", "topiclibre.n_id=toplibnamere.id AND toplibnamere.tq_id=? and state=0 ", tqId).GroupBy("s_type,s_type_re").Find(&tqTypeList)
	return tqTypeList, err
}
func (this *TopicLibRe) GetTQTypeTT(nid int64) ([]TQType, error) {
	tqTypeList := make([]TQType, 0)
	err := Db(0).Select("s_type,s_type_re ,COUNT(1) num ").Table("topiclibre ").Where(" id=qid  and  n_id=? and start=0", nid).GroupBy("s_type,s_type_re").Find(&tqTypeList)
	return tqTypeList, err
}
